package com.example.jnet.network;

import com.example.jnet.pojo.MessageProtocol;
import com.example.jnet.tools.ToolUtils;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

public class MessageDecoder extends ByteToMessageDecoder {
    private static Logger logger = LoggerFactory.getLogger(MessageDecoder.class);

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        try {
            parse(in, out);
        } catch (Exception e) {
            logger.error("" + e.getMessage(), e);
        }
    }

    public void parse(ByteBuf in, List<Object> out) throws Exception {
        int length = in.readableBytes();
        if (length >= MessageProtocol.DEFAULT_HEADER_LENGTH) {
            MessageProtocol messageProtocol = new MessageProtocol();
            parseHeader(in, messageProtocol);

            int dataLen = ToolUtils.bytes2Int(messageProtocol.getLength());
            if (dataLen < MessageProtocol.DEFAULT_HEADER_LENGTH) {
                logger.error("decode msg failed, messageProtocol:" + messageProtocol.toString());
                throw new Exception("dataLen exception: " + dataLen);
            }

            logger.info("type: " + ToolUtils.bytes2Int(messageProtocol.getType()));
            logger.info("id: " + ToolUtils.bytes2Int(messageProtocol.getId()));
            logger.info("cmd: " + ToolUtils.bytes2Int(messageProtocol.getCmd()));
            logger.info("length: " + ToolUtils.bytes2Int(messageProtocol.getLength()));

            dataLen = dataLen - MessageProtocol.DEFAULT_HEADER_LENGTH;
            byte[] arr = new byte[dataLen];
            in.readBytes(arr);
            messageProtocol.setBody(arr);
            out.add(messageProtocol);
        }
    }

    public void parseHeader(ByteBuf in, MessageProtocol messageProtocol) {
        byte[] arr = new byte[4];
        in.readBytes(arr);
        messageProtocol.setType(arr);

        arr = new byte[4];
        in.readBytes(arr);
        messageProtocol.setId(arr);

        arr = new byte[4];
        in.readBytes(arr);
        messageProtocol.setCmd(arr);

        arr = new byte[4];
        in.readBytes(arr);
        messageProtocol.setLength(arr);
    }
}